/*
 * phal_timer.c
 *
 *  Created on: 22/02/2010
 *      Author: gustavo
 */

// ************************* INCLUDES **************************

#include "padl_timer.h"
#include "padl_sysctrl.h"
#include "padl_vic.h"

#include "phal_timer.h"
#include "../config/phal_timer_config.h"

// *********************** DEFINITIONS *************************

#define TIMER_FROM_ID(id) \
	((id == phal_timer_TIMER0) ? (padl_timer_TIMER0) :\
	(id ==phal_timer_TIMER1)  ? (padl_timer_TIMER1) :\
	(id ==phal_timer_TIMER2)  ? (padl_timer_TIMER2) :\
								(padl_timer_TIMER3))

#define PRESCALER_VALUE		0

// *********************** PROTOTYPES **************************

#if TIMER0_ENABLE
static void phal_timer0_interruptRoutine(void);
#endif

#if TIMER1_ENABLE
static void phal_timer1_interruptRoutine(void);
#endif

#if TIMER2_ENABLE
static void phal_timer2_interruptRoutine(void);
#endif

#if TIMER3_ENABLE
static void phal_timer3_interruptRoutine(void);
#endif

// *************************** BODY ****************************

////////////////////////////////////////////////////////////////
/// Timer initialization									 ///
////////////////////////////////////////////////////////////////
void phal_timer_init(void)
{
#if TIMER0_ENABLE
	padl_sysctrl_SET_TIMER0_CLK(padl_sysctrl_PCLKSEL_CCLK_DIV_BY_1);

	padl_timer_START_CONFIG(padl_timer_TIMER0);

	padl_timer_OPERATION_MODE(padl_timer_TIMER0, padl_timer_CTCR_TIMER_MODE);
	padl_timer_SET_PRESCALER(padl_timer_TIMER0, PRESCALER_VALUE);
	padl_timer_SET_MATCH_VALUE(padl_timer_TIMER0, padl_timer_MR_MATCH_CHANNEL_0, padl_sysctrl_GET_SYSTEM_FRQ() / TIMER0_TICK_RATE);
	padl_timer_ENABLE_INTERRUPT_ON_MATCH(padl_timer_TIMER0, padl_timer_MR_MATCH_CHANNEL_0);
	padl_timer_ENABLE_RESET_ON_MATCH(padl_timer_TIMER0, padl_timer_MR_MATCH_CHANNEL_0);
	padl_vic_INSTALL_IRQ(TIMER0_INT, phal_timer0_interruptRoutine, TIMER0_INTERRUPT_PRIORITY);

	padl_timer_FINISH_CONFIG(padl_timer_TIMER0);
#endif
}

////////////////////////////////////////////////////////////////
/// Stop timer operation									 ///
////////////////////////////////////////////////////////////////
void phal_timer_stop(phal_timer_Id timerId)
{
	padl_timer_TURN_OFF(TIMER_FROM_ID(timerId));
}

////////////////////////////////////////////////////////////////
/// Start timer operation									 ///
////////////////////////////////////////////////////////////////
void phal_timer_start(phal_timer_Id timerId)
{
	padl_timer_TURN_ON(TIMER_FROM_ID(timerId));
}

////////////////////////////////////////////////////////////////
/// Timer initialization									 ///
////////////////////////////////////////////////////////////////

#if TIMER0_ENABLE
static void phal_timer0_interruptRoutine(void)
{
	padl_timer_CLEAR_MATCH_INTERRUT(padl_timer_TIMER0, padl_timer_MR_MATCH_CHANNEL_0);

	TIMER0_INTERRUPT_HANDLER();

	padl_vic_ACKNOWLEDGE_INTERRUPT();
}
#endif

#if TIMER1_ENABLE
static void phal_timer1_interruptRoutine(void)
{
	padl_timer_CLEAR_MATCH_INTERRUT(padl_timer_TIMER1, padl_timer_MR_MATCH_CHANNEL_0);

	TIMER1_INTERRUPT_HANDLER();

	padl_vic_ACKNOWLEDGE_INTERRUPT();
}
#endif

#if TIMER2_ENABLE
static void phal_timer2_interruptRoutine(void)
{
	padl_timer_CLEAR_MATCH_INTERRUT(padl_timer_TIMER2, padl_timer_MR_MATCH_CHANNEL_0);

	TIMER2_INTERRUPT_HANDLER();

	padl_vic_ACKNOWLEDGE_INTERRUPT();
}
#endif

#if TIMER3_ENABLE
static void phal_timer3_interruptRoutine(void)
{
	padl_timer_CLEAR_MATCH_INTERRUT(padl_timer_TIMER3, padl_timer_MR_MATCH_CHANNEL_0);

	TIMER3_INTERRUPT_HANDLER();

	padl_vic_ACKNOWLEDGE_INTERRUPT();
}
#endif
